import json
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from binascii import b2a_hex, a2b_hex
import hashlib
import requests
import time
import psutil

# 防止抓包调试模式
FAKE_DEBUG = True

proxies = {
    'http': None,
    'https': None
} if FAKE_DEBUG else {}

class Api:

    def __init__(self, username, apikey, domain, logger):
        self.username = username
        self.apikey = apikey
        self.domain = domain
        self.logger = logger
    
    # 拼接URL前缀
    def _makeURL(self, url):
        return self.domain + url.replace('[username]', self.username)

    # 加密请求体
    def _makeFormBody(self, body):
        body = json.dumps(body)
        aes = AES.new(self.apikey[:16].encode('utf-8'), AES.MODE_ECB)
        pad_pkcs7 = pad(body.encode('utf-8'), AES.block_size, style='pkcs7')
        data = aes.encrypt(pad_pkcs7)
        dataStr = str(b2a_hex(data), encoding="utf-8")
        signStr = "date={}&key={}".format(dataStr, self.apikey)
        sign = hashlib.md5(signStr.encode("utf-8")).hexdigest()

        return {
            'date': dataStr,
            'sign': sign
        }

    # 解密请求参数
    def decodeBody(self, data, sign):
        if not data:
            raise Exception('缺少data参数')

        if not sign:
            raise Exception('缺少sign参数')
        
        signStr = "date={}&key={}".format(str(data), self.apikey)
        checkSign = hashlib.md5(signStr.encode("utf-8")).hexdigest()
        if checkSign != sign:
            raise Exception('请求数据签名错误')

        aes = AES.new(self.apikey[:16].encode('utf-8'), AES.MODE_ECB)
        dataResult = aes.decrypt(a2b_hex(data.lower()))
        dataResult = unpad(dataResult, AES.block_size)
        dataResult = json.loads(dataResult.decode())
        return dataResult


    # 获取公共配置
    def getPublicConfig(self):
        resp = requests.get(self._makeURL('api/public/index'), proxies=proxies)
        resp = resp.json()
        if 'code' in resp and resp['code'] == 'error':
            raise Exception(resp['msg'] if 'msg' in resp else '未知错误')
        return resp

    # 上报用户实时状态
    def reportAccountInfo(self, data):
        now = int(time.time())
        resp = requests.post(self._makeURL('aliclient/[username]/account'), data=self._makeFormBody({
            'login_status': data['login_status'],
            'user_monny': '{:.2f}'.format(data['money']),
            'cpu_percent': psutil.cpu_percent(interval=.8),
            'memory_percent': psutil.virtual_memory().percent,
            'now': now,
            'server_time': int(time.time())
        }), proxies=proxies)
        return resp

    # 通知 - 充值表单信息
    def notifyOrderForm(self, data):
        self.logger.info('------------------ notifyOrderForm START -----------------------')
        self.logger.info(json.dumps({
            'bank_value': data['bank_value'] if 'bank_value' in data else '',
            'bank_action': data['bank_action'] if 'bank_action' in data else '',
            'img_oss': data['img_oss'] if 'img_oss' in data else '',
            'img_value': data['img_value'] if 'img_value' in data else '',
            'order_id': data['order_id'],
            'alipay_order_sn': data['alipay_order_sn'] if 'alipay_order_sn' in data else '',
            'alipay_order_id': data['alipay_order_id'] if 'alipay_order_id' in data else '',
            'amount': data['amount'],
        }))

        resp = requests.post(self._makeURL('aliclient/{}/bank'.format(data['order_id'])), data=self._makeFormBody({
            'bank_value': data['bank_value'] if 'bank_value' in data else '',
            'bank_action': data['bank_action'] if 'bank_action' in data else '',
            'img_oss': data['img_oss'] if 'img_oss' in data else '',
            'img_value': data['img_value'] if 'img_value' in data else '',
            'order_id': data['order_id'],
            'alipay_order_sn': data['alipay_order_sn'] if 'alipay_order_sn' in data else '',
            'alipay_order_id': data['alipay_order_id'] if 'alipay_order_id' in data else '',
            'amount': data['amount'],
        }), proxies=proxies)
        self.logger.info('表单结果上报, 获取接口信息, 订单号 ' + data['order_id'] + ' 内容 ' + resp.text)
        self.logger.info('------------------ notifyOrderForm END -----------------------')
        return resp

    # 通知 - 订单支付结果
    def notifyOrderPaySuccess(self, data):
        self.logger.info('------------------ notifyOrderPaySuccess START -----------------------')
        resp = requests.post(self._makeURL('aliclient/[username]/payorder'), data=self._makeFormBody([{
            'order_id': data['order_id'],
            'ali_order_id': data['ali_order_id'],
            'ali_order_sn': data['ali_order_sn'],
            'pay_money': data['pay_money'],
            'order_money': data['order_money'],
            'pay_date': data['pay_date'],
            'order_date': data['order_date'],
            'bank_code': data['bank_code'],
        }]), proxies=proxies)
        self.logger.info('支付结果上报, 获取接口信息, 订单号 ' + data['order_id'] + ' 内容 ' + resp.text)
        self.logger.info('------------------ notifyOrderPaySuccess END -----------------------')
        return resp
